#include <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <queue>

template <typename T>
class SafeQueue {
 public:
  // 构造函数：设置最大容量（默认60）
  explicit SafeQueue(size_t max_size = 60)
      : max_size_(max_size), stopped_(false) {}

  // 线程安全的阻塞式入队（队列满时等待）
  bool push(T item,
            std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) {
    std::unique_lock<std::mutex> lock(mutex_);
    // 等待队列非满或超时
    if (timeout.count() > 0) {
      if (!cond_push_.wait_for(lock, timeout, [this] {
            return queue_.size() < max_size_ || stopped_;
          })) {
        return false;  // 超时返回失败
      }
    } else {
      cond_push_.wait(lock,
                      [this] { return queue_.size() < max_size_ || stopped_; });
    }

    if (stopped_) return false;
    queue_.push(std::move(item));
    cond_pop_.notify_one();  // 通知可能等待的消费者
    return true;
  }

  // 非阻塞入队（立即返回）
  bool try_push(T item) {
    std::lock_guard<std::mutex> lock(mutex_);
    if (queue_.size() >= max_size_ || stopped_) return false;
    queue_.push(std::move(item));
    cond_pop_.notify_one();
    return true;
  }

  // 出队操作（支持超时）
  bool pop(T& item,
           std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) {
    std::unique_lock<std::mutex> lock(mutex_);
    if (timeout.count() > 0) {
      if (!cond_pop_.wait_for(lock, timeout,
                              [this] { return !queue_.empty() || stopped_; })) {
        return false;  // 超时返回失败
      }
    } else {
      cond_pop_.wait(lock, [this] { return !queue_.empty() || stopped_; });
    }

    if (stopped_ || queue_.empty()) return false;
    item = std::move(queue_.front());
    queue_.pop();
    cond_push_.notify_one();  // 通知可能等待的生产者
    return true;
  }

  // 安全停止所有阻塞操作
  void stop() {
    std::lock_guard<std::mutex> lock(mutex_);
    stopped_ = true;
    cond_push_.notify_all();
    cond_pop_.notify_all();
  }
  void resume() {
    std::lock_guard<std::mutex> lock(mutex_);
    stopped_ = false;
    cond_push_.notify_all();
    cond_pop_.notify_all();
  }
  size_t size() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return queue_.size();
  }

  bool empty() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return queue_.empty();
  }

  bool isStopped() const {
    std::lock_guard<std::mutex> lock(mutex_);
    return stopped_;
  }

  void clear() {
    stop();
    while (!queue_.empty()) {
      auto item = std::move(queue_.front());
      queue_.pop();
      // 释放FFmpeg资源
      if constexpr (std::is_same_v<T, AVPacket*>) {
        av_packet_free(&item);  // 释放AVPacket
      } else if constexpr (std::is_same_v<T, AVFrame*>) {
        av_frame_free(&item);  // 释放AVFrame
      }
    }
    resume();
  }

 private:
  std::queue<T> queue_;
  mutable std::mutex mutex_;
  std::condition_variable cond_pop_;   // 消费者等待条件（非空）
  std::condition_variable cond_push_;  // 生产者等待条件（非满）
  const size_t max_size_;              // 队列容量上限
  std::atomic<bool> stopped_;          // 停止标志
};
